//%define api.value.type {int}
%define api.pure full

%parse-param {yyscan_t scanner} {int* result}
%lex-param    {yyscan_t scanner} 

%union {
    int ival;
}
%token<integer> INTEGER


%code top {
    #include <stdio.h>
    #include "lexer.h"
    #include "ParseContext.h"
    
    static void yyerror(yyscan_t scanner,int *ret, const char* s) {
        fprintf(stderr, "%s\n", s);
    }
}

// Terminals
%token NUMBER PLUS MINUS TIMES UMINUS LPAREN RPAREN

// Precedence and associativity

%left TIMES
%left PLUS MINUS
%left UMINUS

%type <ival> expr
%type <ival> NUMBER 
%type <ival> start 
%%


// Grammar rules

start
    : expr {
        $$ = $1;
        *result = $1;
    }
;

expr
    : 
    NUMBER {
        $$ = $1;
    }
    | expr PLUS expr {
        $$ = $1 + $3;
    }
    | expr MINUS expr {
        $$ = $1 - $3;
    }
    | expr TIMES expr {
        $$ = $1 * $3;
    }
    | MINUS expr %prec UMINUS {
        $$ = -$2;
    }
    | '(' expr ')' {
        $$ = $2;
    }
;

%%